<?php


namespace app\back\model;


use think\facade\Db;
use think\response\Json;
use \Exception;

class RoleModel
{
    private static $_table = 'role'; // 角色表
    private static $_menuTable = 'menu'; // 菜单表

    /**获取角色列表
     * @param $input
     * @param $info
     * @return Json
     */
    public static function getRoleList($input, $info)
    {
        try {
            $map = [
                ['admin_id', '=', $info['id']],
                ['pid', '=', $info['role_id']],
                ['valid', '=', 1]
            ];
            if ($input['status'] !== '') {
                $map[] = ['status', '=', $input['status']];
            }
            if ($input['name'] !== '') $map[] = ['name', 'like', "%{$input['name']}%"];
            $field = 'id,name,status,create_time';
            $table = Db::table(self::$_table)->where($map)->field($field);
            $count = $table->count();
            if ($count == 0) return jsonSuccess('暂无数据', ['count' => 0, 'list' => []]);
            $list = $table->page($input['page'], $input['limit'])->order('create_time', 'desc')->select()->toArray();
            return jsonSuccess('获取成功', ['count' => $count, 'list' => $list]);
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }

    /**添加角色
     * @param $input
     * @param $info
     * @return Json
     */
    public static function addRole($input, $info)
    {
        $flag = false;
        try {
            $insert = [
                'admin_id' => $info['id'],
                'name' => $input['name'],
                'pid' => $info['role_id'],
                'menu_ids' => $input['menu_ids'] == [] ? ',' : ',' . $input['menu_ids'] . ',',
                'left_menu_ids' => ',',
                'level' => $info['role_level'] + 1,
                'path' => $info['role_path'],
                'status' => 1,
                'create_time' => time()
            ];
            Db::startTrans();
            $flag = true;
            $id = Db::table(self::$_table)->insertGetId($insert);
            if ($id < 1) {
                Db::rollback();
                return jsonFail('添加失败');
            }
            $rtn = Db::table(self::$_table)->where('id', $id)->update(['path' => Db::raw("concat(`path`,'{$id}-')")]);
            if ($rtn !== 1) {
                Db::rollback();
                return jsonFail('添加失败');
            }
            Db::commit();
            return jsonSuccess('添加成功');
        } catch (Exception $e) {
            if ($flag == true) Db::rollback();
            return jsonFail('服务内部错误~');
        }
    }

    /**修改角色状态
     * @param $input
     * @param $info
     * @return Json
     */
    public static function changeRoleStatus($input, $info)
    {
        try {
            // 获取当前信息
            $roleInfo = Db::table(self::$_table)->field('path,pid,valid,admin_id')->where('id', $input['id'])->find();
            if (!$roleInfo) return jsonFail('未找到角色信息');
            if ($roleInfo['admin_id'] != $info['id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['pid'] != $info['role_id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['valid'] != 1) return jsonFail('该角色已删除无法继续操作');
            // 根据不同status执行不同操作
            $update = [
                'status' => $input['status']
            ];
            switch ($input['status']) {
                case 1:
                    // 启用角色
                    $map[] = ['id', '=', $input['id']];
                    $map[] = ['admin_id', '=', $info['id']];
                    $map[] = ['valid', '=', 1];
                    $map[] = ['status', '=', 0];
                    $rtn = Db::table(self::$_table)->where($map)->update($update);
                    if ($rtn) return jsonSuccess('操作成功');
                    break;
                case 0:
                    // 联级禁用角色
                    $rtn = Db::table(self::$_table)->whereRaw('`status` = 1 AND `valid` = 1 AND path LIKE :path', ['path' => "{$roleInfo['path']}%"])->update($update);
                    if ($rtn) return jsonSuccess('操作成功');
                    break;
                default:
                    return jsonFail('不可用的状态');
            }
            return jsonFail('操作失败');
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }

    /**删除角色
     * @param $input
     * @param $info
     * @return Json
     */
    public static function delRole($input, $info)
    {
        try {
            // 获取当前信息
            $roleInfo = Db::table(self::$_table)->field('path,pid,valid,admin_id')->where('id', $input['id'])->find();
            if (!$roleInfo) return jsonFail('未找到角色信息');
            if ($roleInfo['admin_id'] != $info['id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['pid'] != $info['role_id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['valid'] == 0) return jsonFail('该角色已删除无法继续操作');
            $update = [
                'valid' => 0
            ];
            // 联级删除角色
            $rtn = Db::table(self::$_table)->whereRaw('`valid` = 1 AND path LIKE :path', ['path' => "{$roleInfo['path']}%"])->update($update);
            if ($rtn) return jsonSuccess('操作成功');
            return jsonFail('操作失败');
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }

    /**获取单个角色信息
     * @param $input
     * @param $info
     * @return Json
     */
    public static function getRoleOnly($input, $info)
    {
        try {
            // 获取当前信息
            $roleInfo = Db::table(self::$_table)->field('id,pid,valid,menu_ids,name,admin_id')->where('id', $input['id'])->find();
            if (!$roleInfo) return jsonFail('未找到角色信息');
            if ($roleInfo['admin_id'] != $info['id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['pid'] != $info['role_id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['valid'] == 0) return jsonFail('该角色已删除无法继续操作');
            $menuList = MenuModel::getAdminAuthStatic($info);
            if (!is_array($menuList)) return $menuList;
            unset($roleInfo['pid']);
            unset($roleInfo['status']);
            // 获取三级权限
            $checkIds = Db::table(self::$_menuTable)->where('level', 2)->field('id')->where('id', 'in', $roleInfo['menu_ids'])->select()->toArray();
            $roleInfo['menu_ids'] = array_column($checkIds, 'id');
            return jsonSuccess('获取成功', ['info' => $roleInfo, 'menuList' => $menuList]);
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }

    /**编辑角色信息
     * @param $input
     * @param $info
     * @return Json
     */
    public static function editRole($input, $info)
    {
        try {
            // 获取当前信息
            $roleInfo = Db::table(self::$_table)->field('id,pid,valid,path,menu_ids,admin_id')->where('id', $input['id'])->find();
            if (!$roleInfo) return jsonFail('未找到角色信息');
            if ($roleInfo['pid'] != $info['role_id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['admin_id'] != $info['id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['valid'] == 0) return jsonFail('该角色已删除无法继续操作');
            $input['menu_ids'] = ',' . $input['menu_ids'] . ',';
            $oldMenuIds = explode(',', $roleInfo['menu_ids']);
            $newMenuIds = explode(',', $input['menu_ids']);
            $diffArr = array_values(array_diff($oldMenuIds, $newMenuIds));
            if ($diffArr) {
                $replace_menu_ids = '';
                $replace_left_menu_ids = '';
                foreach ($diffArr as $k => $v) {
                    if ($k == 0) {
                        $replace_menu_ids = "replace(menu_ids, ',{$v},', ',')";
                        $replace_left_menu_ids .= "replace(menu_ids, ',{$v},', ',')";
                    } else {
                        $replace_menu_ids = "replace(" . $replace_menu_ids . ", ',{$v},', ',')";
                        $replace_left_menu_ids = "replace(" . $replace_left_menu_ids . ", ',{$v},', ',')";
                    }
                }
                $updateStr = "menu_ids = {$replace_menu_ids}, left_menu_ids = {$replace_left_menu_ids}";
                $sql = "update `role` set {$updateStr} where path LIKE '{$roleInfo['path']}%'";
                $rtn = Db::table(self::$_table)->execute($sql);
                if ($rtn) {
                    return jsonSuccess('操作成功');
                } else {
                    return jsonFail('操作失败');
                }
            } else {
                $rtn = Db::table(self::$_table)->update($input);
                if ($rtn == 1) {
                    return jsonSuccess('操作成功');
                } else {
                    return jsonFail('操作失败');
                }
            }

        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }

    /**获取当前管理员下级角色
     * @param $info
     * @return Json
     */
    public static function getAdminRole($info)
    {
        $rtn = self::getAdminRoleStatic($info);
        if (is_array($rtn)) return jsonSuccess('获取成功', $rtn);
        return $rtn;
    }

    /**获取当前管理员下级角色(内部调到)
     * @param $info
     * @return array|Json
     */
    public static function getAdminRoleStatic($info)
    {
        try {
            $map = [
                ['pid', '=', $info['role_id']],
                ['admin_id', '=', $info['id']]
            ];
            $roleInfo = Db::table(self::$_table)->field('id,name')->where($map)->where('status', 1)->select()->toArray();
            if ($roleInfo) return $roleInfo;
            return jsonFail('未找到可用的角色');
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }

    /**获取单个角色菜单信息
     * @param $input
     * @param $info
     * @return Json
     */
    public static function getRoleMenuOnly($input, $info)
    {
        try {
            // 获取当前信息
            $roleInfo = Db::table(self::$_table)->field('id,pid,valid,left_menu_ids,menu_ids,admin_id')->where('id', $input['id'])->find();
            if (!$roleInfo) return jsonFail('未找到角色信息');
            if ($roleInfo['admin_id'] != $info['id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['pid'] != $info['role_id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['valid'] == 0) return jsonFail('该角色已删除无法继续操作');
            $field = 'id,pid,name';
            $map[] = ['id', 'in', $roleInfo['menu_ids']];
            $menuList = Db::table(self::$_menuTable)->field($field)->where($map)->select()->toArray();
            if (!$menuList) return jsonFail('请先添加权限');
            // 获取三级权限
            $checkIds = Db::table(self::$_menuTable)->where('level', 2)->field('id')->where('id', 'in', $roleInfo['left_menu_ids'])->select()->toArray();
            $infoList = [
                'id' => $roleInfo['id'],
                'left_menu_ids' => array_column($checkIds, 'id')
            ];
            return jsonSuccess('获取成功', ['info' => $infoList, 'menuList' => getTree($menuList)]);
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }

    /**编辑角色菜单信息
     * @param $input
     * @param $info
     * @return Json
     */
    public static function editRoleMenu($input, $info)
    {
        try {
            // 获取当前信息
            $roleInfo = Db::table(self::$_table)->field('id,pid,valid')->where('id', $input['id'])->find();
            if (!$roleInfo) return jsonFail('未找到角色信息');
            if ($roleInfo['pid'] != $info['role_id']) return jsonFail('该角色非您直接管理，您没有权限操作');
            if ($roleInfo['valid'] == 0) return jsonFail('该角色已删除无法继续操作');
            $input['left_menu_ids'] = ',' . $input['left_menu_ids'] . ',';
            $rtn = Db::table(self::$_table)->update($input);
            if ($rtn) return jsonSuccess('编辑成功');
            return jsonFail('编辑失败');
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }
}